package com.ssy.lingxi.marketing.serviceimpl.base.coupon;

import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.marketing.entity.coupon.CouponBrandDO;
import com.ssy.lingxi.marketing.entity.coupon.CouponCategoryDO;
import com.ssy.lingxi.marketing.entity.coupon.CouponGoodsDO;
import com.ssy.lingxi.marketing.model.bo.SuitableCategoryBO;
import com.ssy.lingxi.marketing.model.vo.coupon.response.SuitableBrandVO;
import com.ssy.lingxi.marketing.model.vo.coupon.response.SuitableCategoryVO;
import com.ssy.lingxi.marketing.model.vo.coupon.response.SuitableCommoditySkuVO;
import com.ssy.lingxi.marketing.model.vo.coupon.response.SuitablePlatformCommoditySkuVO;
import com.ssy.lingxi.marketing.repository.CouponBrandRepository;
import com.ssy.lingxi.marketing.repository.CouponCategoryRepository;
import com.ssy.lingxi.marketing.repository.CouponGoodsRepository;
import com.ssy.lingxi.marketing.service.feign.IProductFeignService;
import com.ssy.lingxi.product.api.model.response.BrandResponse;
import com.ssy.lingxi.product.api.model.response.commodity.CustomerCategoryResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 基础优惠券商品服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/8/16
 */
@Slf4j
@Service
public class BaseCouponGoodsService {

    @Resource
    private CouponGoodsRepository goodsRepository;
    @Resource
    private CouponCategoryRepository categoryRepository;
    @Resource
    private CouponBrandRepository brandRepository;
    @Resource
    private IProductFeignService productFeignService;

    // ============================商家============================

    /**
     * 查询商家优惠券适用品类
     * @param id 优惠券id
     * @return 返回结果
     */
    public List<List<SuitableCategoryVO>> listMerchantCouponCategory(Long id) {
        List<CouponCategoryDO> categoryDOList = categoryRepository.findAllByCouponId(id);
        return categoryDOList.stream().map(e ->
                e.getCategoryList().stream().map(category -> {
                    SuitableCategoryVO suitableCategoryVO = new SuitableCategoryVO();
                    suitableCategoryVO.setId(category.getId());
                    suitableCategoryVO.setName(category.getName());
                    suitableCategoryVO.setImageUrl(category.getImageUrl());
                    return suitableCategoryVO;
                }).collect(Collectors.toList())
        ).collect(Collectors.toList());
    }

    /**
     * 查询商家优惠券适用品牌
     * @param id 优惠券id
     * @return 返回结果
     */
    public List<SuitableBrandVO> listMerchantCouponBrand(Long id) {
        List<CouponBrandDO> brandDOList = brandRepository.findAllByCouponId(id);
        return brandDOList.stream().map(e -> {
            SuitableBrandVO suitableBrandVO = new SuitableBrandVO();
            suitableBrandVO.setId(e.getBrandId());
            suitableBrandVO.setName(e.getBrandName());
            suitableBrandVO.setLogoUrl(e.getLogo());
            return suitableBrandVO;
        }).collect(Collectors.toList());
    }

    /**
     * 查询商家优惠券适用商品
     * @param id 优惠券id
     * @return 返回结果
     */
    public List<SuitableCommoditySkuVO> listMerchantCouponGoods(Long id) {
        List<CouponGoodsDO> goodsDOList = goodsRepository.findAllByBelongTypeAndCouponId(BelongTypeEnum.MERCHANT.getCode(), id);
        return goodsDOList.stream().map(e -> {
            SuitableCommoditySkuVO suitableCommoditySkuVO = new SuitableCommoditySkuVO();
            suitableCommoditySkuVO.setId(e.getSkuId());
            suitableCommoditySkuVO.setCommodityId(e.getProductId());
            suitableCommoditySkuVO.setName(e.getProductName());
            suitableCommoditySkuVO.setMainPic(e.getProductImgUrl());
            suitableCommoditySkuVO.setCustomerCategoryName(e.getCategory());
            suitableCommoditySkuVO.setBrandName(e.getBrand());
            suitableCommoditySkuVO.setUnitName(e.getUnit());
            suitableCommoditySkuVO.setUnitPrice(e.getPrice());
            return suitableCommoditySkuVO;
        }).collect(Collectors.toList());
    }

    /**
     * 查询商家优惠券适用品类信息
     * @param suitableCategoryList 适用品类
     * @return 返回结果
     */
    public Wrapper<List<CustomerCategoryResponse>> queryMerchantCouponCategory(List<List<Long>> suitableCategoryList) {
        // 每个集合取最后一个品类id, 最后一级品类不能重复
        if (!suitableCategoryList.stream()
                .map(customerCategoryList -> customerCategoryList.stream().skip(customerCategoryList.size() - 1).findFirst().orElse(null))
                .filter(Objects::nonNull)
                .allMatch(new HashSet<>()::add)) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_CATEGROY_NO_REPEAT);
        }

        // 品类id集合(去重)
        List<Long> customerCategoryIdList = suitableCategoryList.stream().flatMap(Collection::stream).distinct().collect(Collectors.toList());
        // 查询品类数据
        Wrapper<List<CustomerCategoryResponse>> customerCategoryWrapper = productFeignService.getCustomerCategoryById(customerCategoryIdList);
        if (ResponseCode.SUCCESS.getCode() != customerCategoryWrapper.getCode()) {
            return Wrapper.fail(customerCategoryWrapper.getCode(), customerCategoryWrapper.getMessage());
        }

        return customerCategoryWrapper;
    }

    /**
     * 查询商家优惠券适用品牌信息
     * @param suitableBrandList 适用品类
     * @return 返回结果
     */
    public Wrapper<List<BrandResponse>> queryMerchantCouponBrand(List<Long> suitableBrandList) {
        // 品牌不能重复
        if (!suitableBrandList.stream().allMatch(new HashSet<>()::add)) {
            return Wrapper.fail(ResponseCode.MARKETING_COUPON_BRAND_NO_REPEAT);
        }

        // 查询品牌数据
        Wrapper<List<BrandResponse>> brandWrapper = productFeignService.getBrandById(suitableBrandList);
        if (ResponseCode.SUCCESS.getCode() != brandWrapper.getCode()) {
            return Wrapper.fail(brandWrapper.getCode(), brandWrapper.getMessage());
        }

        return brandWrapper;
    }

    /**
     * 保存商家优惠券适用品类信息
     * @param suitableCategoryList 适用品类id
     * @param categoryResponseList 适用品类信息
     */
    public void saveMerchantCouponCategory(Long couponId, List<List<Long>> suitableCategoryList, List<CustomerCategoryResponse> categoryResponseList) {
        if (Objects.isNull(couponId)) {
            return;
        }
        if (CollectionUtils.isEmpty(suitableCategoryList)) {
            return;
        }

        // categoryId - customerCategoryResponse
        Map<Long, CustomerCategoryResponse> customerCategoryMap = categoryResponseList.stream().collect(Collectors.toMap(CustomerCategoryResponse::getId, e -> e, (e1, e2) -> e2));

        // 保存的品类优惠券
        List<CouponCategoryDO> categoryDOList = new ArrayList<>();
        for (List<Long> list : suitableCategoryList) {
            Long lastCategoryId = list.get(list.size() - 1);
            CouponCategoryDO couponCategoryDO = new CouponCategoryDO();
            couponCategoryDO.setCouponId(couponId);
            couponCategoryDO.setCategoryId(lastCategoryId);

            // 处理多级品类的数据
            List<SuitableCategoryBO> suitableCategoryBOList = new ArrayList<>();
            for (Long categoryId : list) {
                CustomerCategoryResponse cateGoryResp = customerCategoryMap.get(categoryId);
                SuitableCategoryBO suitableCategoryBO = new SuitableCategoryBO();
                suitableCategoryBO.setId(cateGoryResp.getId());
                suitableCategoryBO.setName(cateGoryResp.getName());
                suitableCategoryBO.setImageUrl(cateGoryResp.getImageUrl());
                suitableCategoryBOList.add(suitableCategoryBO);
            }
            couponCategoryDO.setCategoryList(suitableCategoryBOList);
            categoryDOList.add(couponCategoryDO);
        }
        categoryRepository.saveAll(categoryDOList);
    }

    /**
     * 保存商家优惠券适用品类信息
     * @param suitableBrandList 适用品牌id
     * @param brandResponseList 适用品牌信息
     */
    public void saveMerchantCouponBrand(Long couponId, List<Long> suitableBrandList, List<BrandResponse> brandResponseList) {
        if (Objects.isNull(couponId)) {
            return;
        }
        if (CollectionUtils.isEmpty(suitableBrandList)) {
            return;
        }

        // brandId - brandResponse
        Map<Long, BrandResponse> brandMap = brandResponseList.stream().collect(Collectors.toMap(BrandResponse::getId, e -> e, (e1, e2) -> e2));

        List<CouponBrandDO> couponBrandDOList = new ArrayList<>();
        for (Long brandId : suitableBrandList) {
            BrandResponse brandResponse = brandMap.get(brandId);
            CouponBrandDO couponBrandDO = new CouponBrandDO();
            couponBrandDO.setId(brandId);
            couponBrandDO.setCouponId(couponId);
            couponBrandDO.setBrandId(brandId);
            couponBrandDO.setBrandName(brandResponse.getName());
            couponBrandDO.setLogo(brandResponse.getLogoUrl());
            couponBrandDOList.add(couponBrandDO);
        }
        brandRepository.saveAll(couponBrandDOList);
    }

    /**
     * 保存商家优惠券适用商品
     * @param loginUser 登录用户信息
     * @param couponId 优惠券id
     * @param suitableCommoditySkuList 适用商品
     */
    public void saveMerchantCouponGoods(UserLoginCacheDTO loginUser, Long couponId,
                                        List<SuitableCommoditySkuVO> suitableCommoditySkuList) {
        if (Objects.isNull(couponId)) {
            return;
        }
        if (CollectionUtils.isEmpty(suitableCommoditySkuList)) {
            return;
        }

        List<CouponGoodsDO> couponGoodsDOList = suitableCommoditySkuList.stream().map(vo -> {
            CouponGoodsDO couponGoodsDO = new CouponGoodsDO();
            couponGoodsDO.setCouponId(couponId);
            couponGoodsDO.setBelongType(BelongTypeEnum.MERCHANT.getCode());
            couponGoodsDO.setMemberId(loginUser.getMemberId());
            couponGoodsDO.setMemberName(loginUser.getCompany());
            couponGoodsDO.setRoleId(loginUser.getMemberRoleId());
            couponGoodsDO.setRoleName(loginUser.getMemberRoleName());
            couponGoodsDO.setProductId(vo.getCommodityId());
            couponGoodsDO.setSkuId(vo.getId());
            couponGoodsDO.setProductName(vo.getName());
            couponGoodsDO.setType(null);
            couponGoodsDO.setCategory(vo.getCustomerCategoryName());
            couponGoodsDO.setBrand(vo.getBrandName());
            couponGoodsDO.setUnit(vo.getUnitName());
            couponGoodsDO.setPrice(vo.getUnitPrice());
            couponGoodsDO.setProductImgUrl(vo.getMainPic());
            return couponGoodsDO;
        }).collect(Collectors.toList());

        goodsRepository.saveAll(couponGoodsDOList);
    }

    /**
     * 查询是否存在商家适用品类, 存在则删除
     * @param couponId 优惠券id
     */
    public void existsAndDeleteMerchantCouponCategory(Long couponId) {
        if (categoryRepository.existsByCouponId(couponId)) {
            categoryRepository.deleteByCouponId(couponId);
        }
    }

    /**
     * 查询是否存在商家适用品牌, 存在则删除
     * @param couponId 优惠券id
     */
    public void existsAndDeleteMerchantCouponBrand(Long couponId) {
        if (brandRepository.existsByCouponId(couponId)) {
            brandRepository.deleteByCouponId(couponId);
        }
    }

    /**
     * 查询是否存在商家适用商品, 存在则删除
     * @param couponId 优惠券id
     */
    public void existsAndDeleteCouponGoods(BelongTypeEnum belongType, Long couponId) {
        if (goodsRepository.existsByBelongTypeAndCouponId(belongType.getCode(), couponId)) {
            goodsRepository.deleteByBelongTypeAndCouponId(belongType.getCode(), couponId);
        }
    }

    // ============================平台============================

    /**
     * 查询平台优惠券适用商品
     * @param id 优惠券id
     * @return 返回结果
     */
    public List<SuitablePlatformCommoditySkuVO> listPlatformCouponGoods(Long id) {
        List<CouponGoodsDO> goodsDOList = goodsRepository.findAllByBelongTypeAndCouponId(BelongTypeEnum.PLATFORM.getCode(), id);
        return goodsDOList.stream().map(e -> {
            SuitablePlatformCommoditySkuVO suitableCommoditySkuVO = new SuitablePlatformCommoditySkuVO();
            suitableCommoditySkuVO.setId(e.getSkuId());
            suitableCommoditySkuVO.setCommodityId(e.getProductId());
            suitableCommoditySkuVO.setName(e.getProductName());
            suitableCommoditySkuVO.setMainPic(e.getProductImgUrl());
            suitableCommoditySkuVO.setCustomerCategoryName(e.getCategory());
            suitableCommoditySkuVO.setBrandName(e.getBrand());
            suitableCommoditySkuVO.setUnitName(e.getUnit());
            suitableCommoditySkuVO.setUnitPrice(e.getPrice());
            suitableCommoditySkuVO.setMemberId(e.getMemberId());
            suitableCommoditySkuVO.setRoleId(e.getRoleId());
            suitableCommoditySkuVO.setMemberName(e.getMemberName());
            return suitableCommoditySkuVO;
        }).collect(Collectors.toList());
    }


    /**
     * 保存平台优惠券适用商品
     * @param loginUser 登录用户信息
     * @param couponId 优惠券id
     * @param suitableCommoditySkuList 适用商品
     */
    public void savePlatformCouponGoods(UserLoginCacheDTO loginUser, Long couponId,
                                        List<SuitablePlatformCommoditySkuVO> suitableCommoditySkuList) {
        List<CouponGoodsDO> couponGoodsDOList = suitableCommoditySkuList.stream().map(vo -> {
            CouponGoodsDO goodsDO = new CouponGoodsDO();
            goodsDO.setCouponId(couponId);
            goodsDO.setBelongType(BelongTypeEnum.PLATFORM.getCode());
            goodsDO.setMemberId(vo.getMemberId());
            goodsDO.setMemberName(vo.getMemberName());
            goodsDO.setRoleId(vo.getRoleId());
            goodsDO.setProductId(vo.getCommodityId());
            goodsDO.setSkuId(vo.getId());
            goodsDO.setProductName(vo.getName());
            goodsDO.setType(null);
            goodsDO.setCategory(vo.getCustomerCategoryName());
            goodsDO.setBrand(vo.getBrandName());
            goodsDO.setUnit(vo.getUnitName());
            goodsDO.setPrice(vo.getUnitPrice());
            goodsDO.setProductImgUrl(vo.getMainPic());
            return goodsDO;
        }).collect(Collectors.toList());

        goodsRepository.saveAll(couponGoodsDOList);
    }
}